/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
/*
 * This copy of Woodstox XML processor is licensed under the
 * Apache (Software) License, version 2.0 ("the License").
 * See the License for details about distribution rights, and the
 * specific rights regarding derivate works.
 *
 * You may obtain a copy of the License at:
 *
 * http://www.apache.org/licenses/
 *
 * A copy is also included in the downloadable source code package
 * containing Woodstox, in file "ASL2.0", under the same directory
 * as this file.
 */
package com.je.bpm.api.runtime.process.operator;

import com.google.common.base.Strings;
import com.je.bpm.api.runtime.process.impl.APIProcessModelConverter;
import com.je.bpm.api.runtime.process.operator.desc.ProcessModelGetListParamDesc;
import com.je.bpm.api.runtime.process.operator.validator.ProcessModelGetListOperatorValidator;
import com.je.bpm.common.operation.OperatorEnum;
import com.je.bpm.engine.RepositoryService;
import com.je.bpm.engine.repository.Model;
import com.je.bpm.engine.repository.ModelQuery;
import com.je.bpm.model.process.payloads.ProcessModelGetListPayload;
import com.je.bpm.model.process.results.ProcessModelListResult;
import com.je.bpm.runtime.process.operator.ProcessModelGetListOperator;
import com.je.bpm.runtime.shared.operator.AbstractOperator;
import com.je.bpm.runtime.shared.operator.desc.OperationParamDesc;
import com.je.bpm.runtime.shared.operator.validator.OperatorPayloadParamsValidator;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 获取流程模型集合
 */
public class ProcessModelGetListOperatorImpl extends AbstractOperator<ProcessModelGetListPayload, ProcessModelListResult> implements ProcessModelGetListOperator {

    private OperatorPayloadParamsValidator<ProcessModelGetListPayload> validator = new ProcessModelGetListOperatorValidator();
    private APIProcessModelConverter apiProcessModelConverter;
    private RepositoryService repositoryService;

    public ProcessModelGetListOperatorImpl(APIProcessModelConverter apiProcessModelConverter, RepositoryService repositoryService) {
        this.apiProcessModelConverter = apiProcessModelConverter;
        this.repositoryService = repositoryService;
    }

    @Override
    public OperatorPayloadParamsValidator<ProcessModelGetListPayload> getValidator() {
        return validator;
    }

    @Override
    public String getId() {
        return OperatorEnum.PROCESS_MODEL_LIST_OPERATOR.getId();
    }

    @Override
    public String getName() {
        return OperatorEnum.PROCESS_MODEL_LIST_OPERATOR.getName();
    }

    @Override
    public OperationParamDesc getParamDesc() {
        return new ProcessModelGetListParamDesc();
    }

    @Override
    public ProcessModelGetListPayload paramsParse(Map<String, Object> params) {
        ProcessModelGetListPayload payload = new ProcessModelGetListPayload();
        if (params.get("start") != null && params.get("limit") != null) {
            payload.setStart(formatInteger(params.get("start")));
            payload.setLimit(formatInteger(params.get("limit")));
        }
        payload.setName(params.get("name") == null ? null : params.get("name").toString());
        payload.setKey(params.get("key") == null ? null : params.get("key").toString());
        payload.setCategory(params.get("category") == null ? null : params.get("category").toString());
        payload.setFuncCode(params.get("funcCode") == null ? null : params.get("funcCode").toString());
        payload.setFuncName(params.get("funcName") == null ? null : params.get("funcName").toString());
        payload.setFuncName(params.get("disabled") == null ? null : params.get("disabled").toString());
        payload.setFuncName(params.get("deployStatus") == null ? null : params.get("deployStatus").toString());
        if (params.get("multipleConditionsOrQuery") != null && params.get("multipleConditionsOrQuery").equals("1")) {
            payload.setMultipleConditionsOrQuery(true);
        }
        return payload;
    }

    @Override
    public ProcessModelListResult execute(ProcessModelGetListPayload payload) {
        ModelQuery modelQuery = buildModelQuery(payload);
        List<Model> models;
        if (payload.getLimit() == null) {
            models = modelQuery.list();
        } else {
            models = modelQuery.listPage(payload.getStart(), payload.getLimit());
        }
        List<com.je.bpm.model.process.model.Model> convertedModels = new ArrayList<>();
        for (Model each : models) {
            convertedModels.add(apiProcessModelConverter.from(each));
        }
        return new ProcessModelListResult(payload, convertedModels);
    }

    private ModelQuery buildModelQuery(ProcessModelGetListPayload payload) {
        ModelQuery modelQuery = repositoryService.createModelQuery();
        if (payload.getMultipleConditionsOrQuery()) {
            modelQuery.multipleConditionsOrQuery();
        }
        //nameLike查询
        if (!Strings.isNullOrEmpty(payload.getName())) {
            modelQuery.modelNameLike(payload.getName());
        }

        //key查询
        if (!Strings.isNullOrEmpty(payload.getKey())) {
            modelQuery.modelKey(payload.getKey());
        }

        //流程分类查询
        if (!Strings.isNullOrEmpty(payload.getCategory())) {
            modelQuery.modelCategory(payload.getCategory());
        }

        //功能code
        if (!Strings.isNullOrEmpty(payload.getFuncCode())) {
            modelQuery.modelFuncCode(payload.getFuncCode());
        }

        //功能名称
        if (!Strings.isNullOrEmpty(payload.getFuncName())) {
            modelQuery.modelFuncName(payload.getFuncName());
        }

        //功能名称
        if (!Strings.isNullOrEmpty(payload.getDeployStatus())) {
            modelQuery.modelFuncName(payload.getFuncName());
        }

        //功能名称
        if (!Strings.isNullOrEmpty(payload.getDisabled())) {
            modelQuery.modelFuncName(payload.getFuncName());
        }

        //是否禁用
        if (!Strings.isNullOrEmpty(payload.getDisabled())) {
            modelQuery.disabled(Integer.parseInt(payload.getDisabled()));
        }

        //是否部署
        if (!Strings.isNullOrEmpty(payload.getDeployStatus())) {
            modelQuery.deployStatus(Integer.parseInt(payload.getDeployStatus()));
        }

        return modelQuery;
    }

}
